package com.project.biz.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.framework.core.remove.RemoveFolder;
import com.framework.core.text.MD5Util;
import com.project.biz.*;
import com.project.common.enums.LoginEnum;
import com.project.common.exception.ServiceException;
import com.project.entity.CmsUser;
import com.project.entity.CmsUserBalance;
import com.project.mapper.CmsUserMapper;
import com.project.pojo.dto.TuserDTO;
import com.project.pojo.dto.UserDTO;
import com.project.pojo.dto.UserLoginDTO;
import com.project.pojo.dto.UserLoginPcDTO;
import com.project.pojo.model.*;
import com.project.pojo.vo.UserLoginVO;
import com.project.redis.RedisClient2;
import com.project.util.EmojiUtil;
import com.project.util.MlrtSmsUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
* @Description:   用户服务业务层接口实现类
* @Author:         wangzhiqiang
* @CreateDate:     2019-02-27 9:21
* @Version:        1.0
*/
@Slf4j
@Service
public class UserBizImpl extends ServiceImpl<CmsUserMapper, CmsUser> implements UserBiz {

    /**
     * 用于生成邀请码
     */
    private static char[] chars = new char[]{'A','B','C','E','E','F', 'G', 'H','J','K','L','M','N','P','Q', 'R','S','T','U','V','W','X', 'Y', 'Z', '1','2','3','4','5','6','7', '8', '9'};

    /**
     * 操作日志
     */
    @Autowired
    private CmsOperationLogBiz operationLogBiz;

    /**
     * 用户缓存信息
     */
    @Autowired
    private RedisBiz redisBiz;

    /**
     * 国际化
     */
    @Autowired
    private I18nBiz i18nBiz;

    /**
     * 用户余额
     */
    @Autowired
    private CmsUserBalanceBiz userBalanceBiz;

    /**
     * 注入自身
     */
    @Lazy
    @Autowired
    private UserBiz userBiz;

    /**
     * Redis服务
     */
    @Autowired
    private RedisClient2 redisClient2;

    /**
     * Redis统计信息缓存
     */
    @Autowired
    private RedisBiz2 redisBiz2;

    /**
     * 根据条件获取用户信息
     * @param userQuery
     * @return
     */
    public List<UserDTO> getUser(UserQuery userQuery){
        return this.baseMapper.selectUserByQuery(userQuery);
    }

    /**
     * 按条件分页查询用户及上级信息
     * @param userQuery
     * @return
     */
    public IPage<UserDTO> selectUserByQuery(UserQuery userQuery){
        Page<UserDTO> page = new Page<>(userQuery.getPageNo(), userQuery.getPageSize());
        IPage<UserDTO> iPage = this.baseMapper.selectUserByQuery(page, userQuery);
        return iPage;
    }

    /**
     * 分页查询用户列表
     * @return
     */
    public IPage<CmsUser> getUserByCondition(UserQuery userQuery){
        Page<CmsUser> page = new Page<>();
        page.setCurrent(userQuery.getPageNo());
        page.setSize(userQuery.getPageSize());
        QueryWrapper<CmsUser> queryWrapper = new QueryWrapper<>();
        if (null != userQuery.getBaseUserId()){
            queryWrapper.eq("base_user_id", userQuery.getBaseUserId());
        }
        if (null != userQuery.getBaseUserIds() && userQuery.getBaseUserIds().size() > 0){
            queryWrapper.in("base_user_id", userQuery.getBaseUserIds());
        }
        if (null != userQuery.getParentId()){
            queryWrapper.eq("parent_id", userQuery.getParentId());
        }
        if (StringUtils.isNotBlank(userQuery.getMobile())){
            queryWrapper.like("mobile", userQuery.getMobile());
        }
        if (StringUtils.isNotBlank(userQuery.getWxNickname())){
            queryWrapper.like("wx_nickname", userQuery.getWxNickname());
        }
        if (null != userQuery.getUserType()){
            queryWrapper.eq("user_type", userQuery.getUserType());
        }
        if (null != userQuery.getUserTypes()){
            queryWrapper.in("user_type", userQuery.getUserTypes());
        }
        if (null != userQuery.getPcUserType()){
            queryWrapper.eq("pc_user_type", userQuery.getPcUserType());
        }

        queryWrapper.eq("status", 1);
        queryWrapper.orderByDesc("base_user_id");
        return this.baseMapper.selectPage(page, queryWrapper);
    }

    /**
     * 代理查询用户列表
     * @return
     */
    public IPage<UserDTO> getAgentUsers(UserQuery userQuery){
        return this.selectUserByQuery(userQuery);
    }

    /**
     * 用户登录
     * @return
     */
    @Transactional(rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
    public UserLoginVO login(UserLoginPcDTO userLoginPcDTO, HttpServletRequest request){
        //根据手机号查询用户
        CmsUser cmsUser = this.getUserByMobile(userLoginPcDTO.getMobile());

        if (null == cmsUser){
            throw new ServiceException(this.i18nBiz.getMessage("msg.loginAccountIsNotYetRegistered"));
        }
        String password = MD5Util.getEncryptedPwd(userLoginPcDTO.getPassWord(), LoginEnum.ENCRYPTION_KEY.Value());

        if (!cmsUser.getPassword().equals(password)){
            throw new ServiceException(this.i18nBiz.getMessage("msg.incorrectPassword"));
        }
        //账号被冻结
        if (cmsUser.getState().intValue() == -1){
            throw new ServiceException(this.i18nBiz.getMessage("msg.accountHasBeenSuspended"));
        }

        //生成随机字符串当做token
        String token = RandomStringUtils.randomAlphanumeric(32);

        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setToken(token);
        userLoginVO.setBaseUserId(cmsUser.getBaseUserId());
        userLoginVO.setWxNickname(cmsUser.getWxNickname());
        userLoginVO.setWxPortrait(cmsUser.getWxPortrait());
        userLoginVO.setGender(cmsUser.getGender());
        userLoginVO.setUserType(cmsUser.getUserType());
        userLoginVO.setPcUserType(cmsUser.getPcUserType());

        //后台用户类型（0:普通用户,1:后台管理员）
        if (cmsUser.getPcUserType().intValue() == 1){
            this.operationLogBiz.addOperationLog(cmsUser.getBaseUserId(), "超管账号["+ cmsUser.getMobile()+"]登录成功");
        }else if (cmsUser.getPcUserType().intValue() == 2){
            this.operationLogBiz.addOperationLog(cmsUser.getBaseUserId(), "代理账号["+ cmsUser.getMobile()+"]登录成功");
        }

        //更新最后登录时间
        cmsUser.setLastLoginTime(new Date());
        this.baseMapper.updateById(cmsUser);
        return userLoginVO;
    }

    /**
     * 用户登录（根据验证码登录）
     * @return
     */
    @Transactional(rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
    public UserLoginVO userLogin(UserLoginDTO userLoginDTO){
        //用户登录分布式锁
        String userLogin_lock = "USER_LOGIN_LOCK_" + userLoginDTO.getMobile() ;
        //超时时间（15秒）
        Long expires = System.currentTimeMillis() + 15 * 1000;
        //用户登录的手机号加锁
        if (this.redisClient2.lock(userLogin_lock, String.valueOf(expires))){
            try {
                if (userLoginDTO.getCode().equals("654321")){
                    //TODO 测试使用,不用发送验证码，验证码输入654321即可
                }else {
                    String redisCode = this.findCodeById(userLoginDTO.getMobile());
                    //验证验证码
                    if (null == redisCode || !redisCode.equals(userLoginDTO.getCode())){
                        throw new ServiceException(this.i18nBiz.getMessage("msg.incorrectVerificationCode"));
                    }
                }

                //根据手机号查询用户
                CmsUser cmsUser = this.getUserByMobile(userLoginDTO.getMobile());

                if (null != cmsUser){
                    //账号被冻结
                    if (cmsUser.getState().intValue() == -1){
                        throw new ServiceException(this.i18nBiz.getMessage("msg.accountHasBeenSuspended"));
                    }
                }else {
                    cmsUser = new CmsUser();
                    int i = 0;
                    while (i == 0){
                        //生成六位邀请码,并验证数据库是否存在,存在时重新生成,直到数据库不存在为止
                        String invitationCode = RandomStringUtils.random(6, chars);
                        CmsUser oldUser = this.getUserByInvitationCode(invitationCode);
                        if (null == oldUser){
                            cmsUser.setInvitationCode(invitationCode);
                            i = 1;
                        }
                    }

                    //默认头像数组,用户注册时随机获取一个
                    String[] wx_portraits = {"https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743510614.png",
                    "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743651947.png",
                    "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743667598.png",
                    "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743681974.png",
                    "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743697065.png"};
                    Random rand = new Random();
                    int num = rand.nextInt(5);

                    //为用户设置默认头像
                    cmsUser.setWxPortrait(wx_portraits[num]);

                    Date nowTime = new Date();
                    //微信昵称,使用手机号,中间四位加*
                    String wxNickname = userLoginDTO.getMobile().substring(0, 4) + "****" + userLoginDTO.getMobile().substring(8, 11);
                    cmsUser.setMobile(userLoginDTO.getMobile());
                    cmsUser.setUserType(0);//用户类型（0:普通用户,1:回收员）
                    cmsUser.setUserType(0);
                    cmsUser.setPcUserType(0);
                    cmsUser.setWxNickname(wxNickname);
                    cmsUser.setCreateTime(nowTime);
                    cmsUser.setLastLoginTime(nowTime);
                    cmsUser.setUpdateTime(nowTime);
                    cmsUser.setStatus(1);
                    cmsUser.setState(1);

                    //添加用户
                    int result = this.baseMapper.insert(cmsUser);
                    log.info("用户[{}]注册执行结果:{}", cmsUser.getMobile(), result);
                    CmsUserBalance userBalance = new CmsUserBalance();
                    userBalance.setBaseUserId(cmsUser.getBaseUserId());
                    userBalance.setBalance(new BigDecimal("0.00"));
                    userBalance.setFrozenAmount(new BigDecimal("0.00"));
                    boolean insertUserBalance = this.userBalanceBiz.save(userBalance);
                    log.info("用户注册完成后添加用户余额表执行状态:{}", insertUserBalance);
                }

                //生成随机字符串当做token
                String token = RandomStringUtils.randomAlphanumeric(32);

                UserLoginVO userLoginVO = new UserLoginVO();
                userLoginVO.setToken(token);
                userLoginVO.setBaseUserId(cmsUser.getBaseUserId());
                userLoginVO.setWxNickname(cmsUser.getWxNickname());
                userLoginVO.setWxPortrait(cmsUser.getWxPortrait());
                userLoginVO.setGender(cmsUser.getGender());
                userLoginVO.setUserType(cmsUser.getUserType());
                userLoginVO.setPcUserType(cmsUser.getPcUserType());

                //后台用户类型（0:普通用户,1:后台管理员）
                if (cmsUser.getPcUserType().intValue() == 1){
                    this.operationLogBiz.addOperationLog(cmsUser.getBaseUserId(), "超管账号["+ cmsUser.getMobile()+"]登录成功");
                }else if (cmsUser.getPcUserType().intValue() == 2){
                    this.operationLogBiz.addOperationLog(cmsUser.getBaseUserId(), "代理账号["+ cmsUser.getMobile()+"]登录成功");
                }

                //更新最后登录时间
                cmsUser.setLastLoginTime(new Date());
                this.baseMapper.updateById(cmsUser);
                return userLoginVO;
            }catch (Exception e){
                log.info("用户登录（根据验证码登录）时发生异常,异常信息：{}", e.getMessage());
                throw new ServiceException(e.getMessage());
            }finally {
                //解锁
                this.redisClient2.unlock(userLogin_lock, String.valueOf(expires));
            }
        }

        return null;
    }

    /**
     * 注册
     * @param userRegisterModel
     * @return 0失败,1：成功
     */
    public Integer userRegister(UserRegisterModel userRegisterModel){
        int result = 0;
        //注册分布式锁
        String register_lock = "REGISTER_LOCK_" + userRegisterModel.getMobile() ;
        //超时时间（15秒）
        Long expires = System.currentTimeMillis() + 15 * 1000;
        //注册的手机号加锁
        if (this.redisClient2.lock(register_lock, String.valueOf(expires))){
            try {
                result = this.userBiz.doUserRegister(userRegisterModel);
            }catch (Exception e){
                log.info("注册时发生异常,注册参数信息:{},异常信息：{}", userRegisterModel, e.getMessage());
                throw new ServiceException(e.getMessage());
            }finally {
                //解锁
                this.redisClient2.unlock(register_lock, String.valueOf(expires));
            }
        }
        return result;
    }

    /**
     * 执行用户注册操作
     * @param userRegisterModel
     * @return 0失败,1：成功
     * @return
     */
    @Transactional(rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
    public int doUserRegister(UserRegisterModel userRegisterModel){
        if (EmojiUtil.containsEmoji(userRegisterModel.getWxNickname())){
            throw new ServiceException(this.i18nBiz.getMessage("msg.nicknamesEmoticons"));
        }
        CmsUser mobileUser = this.getUserByMobile(userRegisterModel.getMobile());
        if (null != mobileUser){
            throw new ServiceException(this.i18nBiz.getMessage("msg.mobileNumberRegistered"));
        }

        //邀请码用户
        CmsUser invitationCodeUser = this.getUserByInvitationCode(userRegisterModel.getInvitationCode());
        if (null == invitationCodeUser){
            throw new ServiceException(this.i18nBiz.getMessage("msg.invitationCodeDoesNotExist"));
        }else if (invitationCodeUser.getState().intValue() == -1){
            throw new ServiceException(this.i18nBiz.getMessage("msg.invalidInvitationCode"));
        }

        CmsUser newUser = new CmsUser();
        BeanUtils.copyProperties(userRegisterModel, newUser);

        //邀请码不为空时获取上级用户
        if (StringUtils.isNotBlank(userRegisterModel.getInvitationCode())){
            CmsUser parentUser = this.getUserByInvitationCode(userRegisterModel.getInvitationCode());
            if (null != parentUser){
                newUser.setParentId(parentUser.getBaseUserId());
            }
        }

        //密码加密
        String password = MD5Util.getEncryptedPwd(userRegisterModel.getPassword(), LoginEnum.ENCRYPTION_KEY.Value());
        newUser.setPassword(password);

        int i = 0;
        while (i == 0){
            //生成六位邀请码,并验证数据库是否存在,存在时重新生成,直到数据库不存在为止
            String invitationCode = RandomStringUtils.random(6, chars);
            CmsUser oldUser = this.getUserByInvitationCode(invitationCode);
            if (null == oldUser){
                newUser.setInvitationCode(invitationCode);
                i = 1;
            }
        }
        //默认头像数组,用户注册时随机获取一个
        String[] wx_portraits = {"https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743510614.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743651947.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743667598.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743681974.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743697065.png"};
        Random rand = new Random();
        int num = rand.nextInt(5);

        //为用户设置默认头像
        newUser.setWxPortrait(wx_portraits[num]);

        BigDecimal amount = new BigDecimal("0.00");

        newUser.setUserType(0);//用户类型（0:普通用户,1:经理,2:总监,3:总经理）
        Date nowTime = new Date();
        newUser.setUserType(0);
        newUser.setPcUserType(0);
        newUser.setCreateTime(nowTime);
        newUser.setLastLoginTime(nowTime);
        newUser.setUpdateTime(nowTime);
        newUser.setStatus(1);
        newUser.setState(1);
        newUser.setTaskNumber(0);//新用户初始化每天5次任务数

        //添加用户
        int result = this.baseMapper.insert(newUser);

        if (result > 0){
            CmsUserBalance userBalance = new CmsUserBalance();
            userBalance.setBaseUserId(newUser.getBaseUserId());
            userBalance.setBalance(amount);
            userBalance.setFrozenAmount(amount);
            boolean insertUserBalance = this.userBalanceBiz.save(userBalance);
            log.info("用户注册完成后添加用户余额表执行状态:{}", insertUserBalance);
        }

        return result;
    }

    /**
     * 根据邀请码获取用户
     * @param invitationCode
     * @return
     */
    public CmsUser getUserByInvitationCode(String invitationCode){
        QueryWrapper<CmsUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("invitation_code", invitationCode);

        //根据邀请码查找用户
        CmsUser cmsUser = this.baseMapper.selectOne(queryWrapper);

        return cmsUser;
    }

    /**
     * 根据手机号获取用户
     * @param mobile
     * @return
     */
    public CmsUser getUserByMobile(String mobile){
        QueryWrapper<CmsUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", mobile);

        //根据手机号获取用户
        CmsUser cmsUser = this.baseMapper.selectOne(queryWrapper);

        return cmsUser;
    }

    /**
     * 修改个人信息
     * @param updateUserModel
     * @param userId
     * @return
     */
    public Integer updateUserInfo(UpdateUserModel updateUserModel, Long userId){
        CmsUser user = this.baseMapper.selectById(userId);
        if (null != user){
            if (StringUtils.isNotBlank(updateUserModel.getWxPortrait())){
                user.setWxPortrait(updateUserModel.getWxPortrait());
            }
            if (StringUtils.isNotBlank(updateUserModel.getWxNickname())){
                user.setWxNickname(updateUserModel.getWxNickname());
            }
            if (null != updateUserModel.getGender()){
                user.setGender(updateUserModel.getGender());
            }
            if (StringUtils.isNotBlank(updateUserModel.getSignature())){
                user.setSignature(updateUserModel.getSignature());
            }

            user.setRealName(updateUserModel.getRealName());
            user.setQqNumber(updateUserModel.getQqNumber());
            return this.baseMapper.updateById(user);
        }

        return 0;
    }

    /**
     * 设置支付密码
     * @param updatePayPasswordModel
     * @param userId
     * @return
     */
    public Integer updatePayPassword(UpdatePayPasswordModel updatePayPasswordModel, Long userId){
        CmsUser user = this.baseMapper.selectById(userId);
        if (null != user){
            //支付密码加密
            String password = MD5Util.getEncryptedPwd(updatePayPasswordModel.getPayPassword1(), LoginEnum.ENCRYPTION_KEY.Value());
            user.setPayPassword(password);

            return this.baseMapper.updateById(user);
        }
        return 0;
    }

    /**
     * 修改支付密码
     * @param editPayPasswordModel
     * @return
     */
    public Integer editPayPassword(EditPayPasswordModel editPayPasswordModel, Long userId){
        CmsUser user = this.baseMapper.selectById(userId);
        if (null != user){
            //支付密码加密
            String password = MD5Util.getEncryptedPwd(editPayPasswordModel.getPayPassword(), LoginEnum.ENCRYPTION_KEY.Value());
            user.setPayPassword(password);
            user.setUpdateTime(new Date());
            return this.baseMapper.updateById(user);
        }
        return 0;
    }

    /**
     * 修改支付密码（根据登录密码验证）
     * @param editPayPasswordByLoginModel
     * @return
     */
    public Integer editPayPasswordByLogin(EditPayPasswordByLoginModel editPayPasswordByLoginModel, Long userId){
        CmsUser user = this.baseMapper.selectById(userId);
        if (null != user){
            //登录密码加密
            String loginPassword = MD5Util.getEncryptedPwd(editPayPasswordByLoginModel.getLoginPassword(), LoginEnum.ENCRYPTION_KEY.Value());
            if (!user.getPassword().equals(loginPassword)){
                throw new ServiceException(this.i18nBiz.getMessage("validation.loginPassowrdError"));
            }

            String newPassword = MD5Util.getEncryptedPwd(editPayPasswordByLoginModel.getPayPassword(), LoginEnum.ENCRYPTION_KEY.Value());
            user.setPayPassword(newPassword);
            user.setUpdateTime(new Date());
            return this.baseMapper.updateById(user);
        }
        return 0;
    }

    /**
     * 添加后台用户
     * @param addPcUserModel
     * @param userId
     * @return
     */
    @Transactional(rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
    public Integer addPcUser(AddPcUserModel addPcUserModel, Long userId){
        CmsUser mobileUser = this.getUserByMobile(addPcUserModel.getMobile());
        if (null != mobileUser){
            throw new ServiceException(this.i18nBiz.getMessage("msg.mobileNumberRegistered"));
        }

        CmsUser user = new CmsUser();
        BeanUtils.copyProperties(addPcUserModel, user);

        user.setCreateUser(userId);
        user.setCreateTime(new Date());

        //密码加密
        String password = MD5Util.getEncryptedPwd(addPcUserModel.getPassword(), LoginEnum.ENCRYPTION_KEY.Value());
        user.setPassword(password);

        int i = 0;
        while (i == 0){
            //生成六位邀请码,并验证数据库是否存在,存在时重新生成,直到数据库不存在为止
            String invitationCode = RandomStringUtils.random(6, chars);
            CmsUser oldUser = this.getUserByInvitationCode(invitationCode);
            if (null == oldUser){
                user.setInvitationCode(invitationCode);
                i = 1;
            }
        }

        //默认头像数组,用户注册时随机获取一个
        String[] wx_portraits = {"https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743510614.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743651947.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743667598.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743681974.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743697065.png"};
        Random rand = new Random();
        int num = rand.nextInt(5);

        //为用户设置默认头像
        user.setWxPortrait(wx_portraits[num]);

        user.setPcUserType(1);//后台用户类型（0:普通用户,1:后台管理员）
        user.setStatus(1);
        user.setState(1);
        user.setTaskNumber(0);

        int result = this.baseMapper.insert(user);

        if (result > 0){
            BigDecimal amount = new BigDecimal("0.00");
            CmsUserBalance userBalance = new CmsUserBalance();
            userBalance.setBaseUserId(user.getBaseUserId());
            userBalance.setBalance(amount);
            userBalance.setFrozenAmount(amount);
            boolean insertUserBalance = this.userBalanceBiz.save(userBalance);
            log.info("添加后台用户完成后添加用户余额表执行状态:{}", insertUserBalance);
        }

        return result;
    }

    /**
     * 设置缓存用户信息
     * @param users
     * @return
     */
    public int setTUsers(TuserDTO users){
        boolean setState = this.redisClient2.set("TUSERS", JSONObject.toJSONString(users));
        return setState ? 1 : 0;
    }

    /**
     * 获取缓存用户信息
     * @return
     */
    public TuserDTO getTUsers(){
        if (this.redisClient2.hasKey("TUSERS")){
            String tusersString = this.redisClient2.get("TUSERS");
            TuserDTO result = JSONObject.parseObject(tusersString, TuserDTO.class);
            return result;
        }
        return null;
    }

    /**
     * 删除缓存用户信息
     * @return
     */
    public void delTusers(){
        if (this.redisClient2.hasKey("TUSERS")){
            this.redisClient2.del("TUSERS");
        }
    }

    /**
     * 发送验证码
     * @param mobile
     * @param code
     * @return
     */
    public boolean sendValidateCode(String mobile, String code){
        boolean returnCode = MlrtSmsUtil.sendMobileMsg(mobile, code);
        return returnCode;
    }

    /**
     * 修改密码/忘记密码
     * @param updatePasswordModel
     * @return
     */
    public Integer updatePassword(UpdatePasswordModel updatePasswordModel, Long userId){
        CmsUser user = this.baseMapper.selectById(userId);
        if (null != user){
            //密码加密
            String password = MD5Util.getEncryptedPwd(updatePasswordModel.getPassword(), LoginEnum.ENCRYPTION_KEY.Value());
            user.setPassword(password);
            user.setUpdateTime(new Date());
            return this.baseMapper.updateById(user);
        }
        return 0;
    }

    /**
     * 根据旧密码修改密码
     * @param updatePasswordByPasswordModel
     * @param userId
     * @return
     */
    public int updatePasswordByPasswordModel(UpdatePasswordByPasswordModel updatePasswordByPasswordModel, Long userId){
        CmsUser user = this.baseMapper.selectById(userId);
        if (null != user){
            //密码加密
            String oldPassword = MD5Util.getEncryptedPwd(updatePasswordByPasswordModel.getOldPassword(), LoginEnum.ENCRYPTION_KEY.Value());
            if (!user.getPassword().equals(oldPassword)){
                throw new ServiceException(this.i18nBiz.getMessage("validation.oldPassowrdError"));
            }

            String newPassword = MD5Util.getEncryptedPwd(updatePasswordByPasswordModel.getPassword(), LoginEnum.ENCRYPTION_KEY.Value());
            user.setPassword(newPassword);
            user.setUpdateTime(new Date());
            return this.baseMapper.updateById(user);
        }
        return 0;
    }

    /**
     * 设置缓存
     * @param mobile
     * @return
     */
    public String saveVerifyCode(String mobile) {
        String code = RandomStringUtils.randomNumeric(6);
        this.redisBiz.saveVerifyCode(mobile, code);
        log.info("为手机号["+ mobile +"]缓存验证码: " + code);
        return code;
    }

    /**
     * 获取验证码
     * @param mobile
     * @return
     */
    public String findCodeById(String mobile) {
        return this.redisBiz.getVerifyCode(mobile);
    }

    /**
     * 清除验证码缓存
     * @param mobile
     */
    public void delVerifyCode(String mobile){
        this.redisBiz.delVerifyCode(mobile);
        log.info("清空手机号["+ mobile +"]缓存的验证码");
    }

    /**
     * 根据用户ID获取所有子集用户,不包括自身
     * @param userId
     * @return
     */
    public List<CmsUser> getChilderUsers(Long userId){
        List<CmsUser> allUsers = new ArrayList<>();

        List<Long> user1Ids = new ArrayList<>();
        user1Ids.add(userId);

        boolean whileSwitch = true;
        while (whileSwitch){
            //根据上级查询子集
            QueryWrapper<CmsUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("parent_id", user1Ids);
            List<CmsUser> users = this.baseMapper.selectList(queryWrapper);
            if (null != users && users.size() > 0){
                allUsers.addAll(users);
                user1Ids = new ArrayList<>();
                for (CmsUser u : users){
                    user1Ids.add(u.getBaseUserId());
                }
            }else {
                whileSwitch = false;
            }
        }

        return allUsers;
    }

    /**
     * 根据父级查询子集
     * @param userId
     * @return
     */
    public List<CmsUser> getByParentId(Long userId){
        QueryWrapper<CmsUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", userId);
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 后台-添加普通用户
     * @param pcAddUserModel
     * @param userId 操作人ID
     * @return
     */
    @Transactional(rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
    public int addUser(PcAddUserModel pcAddUserModel, Long userId){
        CmsUser mobileUser = this.getUserByMobile(pcAddUserModel.getMobile());
        if (null != mobileUser){
            throw new ServiceException(this.i18nBiz.getMessage("msg.mobileNumberRegistered"));
        }

        //根据手机号查询上级用户
        CmsUser parentUser = this.getUserByMobile(pcAddUserModel.getParentMobile());
        if (null == parentUser){
            throw new ServiceException(this.i18nBiz.getMessage("msg.parentMobileNoRegister"));
        }
        CmsUser user = new CmsUser();
        BeanUtils.copyProperties(pcAddUserModel, user);

        user.setParentId(parentUser.getBaseUserId());
        user.setCreateUser(userId);
        user.setCreateTime(new Date());

        //密码加密
        String password = MD5Util.getEncryptedPwd(pcAddUserModel.getPassword(), LoginEnum.ENCRYPTION_KEY.Value());
        user.setPassword(password);

        int i = 0;
        while (i == 0){
            //生成六位邀请码,并验证数据库是否存在,存在时重新生成,直到数据库不存在为止
            String invitationCode = RandomStringUtils.random(6, chars);
            CmsUser oldUser = this.getUserByInvitationCode(invitationCode);
            if (null == oldUser){
                user.setInvitationCode(invitationCode);
                i = 1;
            }
        }

        //默认头像数组,用户注册时随机获取一个
        String[] wx_portraits = {"https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743510614.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743651947.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743667598.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743681974.png",
                "https://www.xiangjiapl.com/elephant-family-img/product/20201212/1607743697065.png"};
        Random rand = new Random();
        int num = rand.nextInt(5);

        //为用户设置默认头像
        user.setWxPortrait(wx_portraits[num]);

        user.setUserType(0);//用户类型（0:普通用户,1:回收员）
        user.setPcUserType(0);//后台用户类型（0:普通用户,1:后台管理员）
        user.setState(1);//业务状态（-1:冻结,1:正常）
        user.setStatus(1);//删除标志（-1:删除,1:正常）
        user.setTaskNumber(0);//新用户初始化每天2次任务数

        int result = this.baseMapper.insert(user);

        if (result > 0){
            BigDecimal amount = new BigDecimal("0.00");
            CmsUserBalance userBalance = new CmsUserBalance();
            userBalance.setBaseUserId(user.getBaseUserId());
            userBalance.setBalance(amount);
            userBalance.setFrozenAmount(amount);
            boolean insertUserBalance = this.userBalanceBiz.save(userBalance);
            log.info("后台-添加普通用户完成后添加用户余额表执行状态:{}", insertUserBalance);

            CmsUser operationUser = this.baseMapper.selectById(userId);
            //后台用户类型（0:普通用户,1:后台管理员）
            if (operationUser.getPcUserType().intValue() == 1){
                this.operationLogBiz.addOperationLog(operationUser.getBaseUserId(), "超管账号["+operationUser.getMobile()+"]后台添加用户["+user.getMobile()+"]");
            }
        }

        return result;
    }

    /**
     * 冻结/解冻用户
     * @param frozenOrThawUserModel
     * @param updateUser
     * @return
     */
    @Transactional(rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)
    public int frozenOrThawUser(FrozenOrThawUserModel frozenOrThawUserModel, Long updateUser){
        int result = 0;
        CmsUser user = this.baseMapper.selectById(frozenOrThawUserModel.getUserId());
        if (null == user){
            throw new ServiceException(this.i18nBiz.getMessage("msg.selectedUserDoesNotExist"));
        }
        if (frozenOrThawUserModel.getType().intValue() == 1){
            user.setState(-1);//业务状态（-1:冻结,1:正常）
        }else if (frozenOrThawUserModel.getType().intValue() == 2){
            user.setState(1);//业务状态（-1:冻结,1:正常）
        }
        user.setUpdateTime(new Date());
        user.setUpdateUser(updateUser);
        result = this.baseMapper.updateById(user);
        if (result > 0){
            //冻结时使冻结账户下线
            if (frozenOrThawUserModel.getType().intValue() == 1){
                this.redisBiz.offlineUser(user.getBaseUserId());
            }

            CmsUser operationUser = this.baseMapper.selectById(updateUser);
            //后台用户类型（0:普通用户,1:后台管理员）
            if (operationUser.getPcUserType().intValue() == 1){
                if (frozenOrThawUserModel.getType().intValue() == 1){
                    this.operationLogBiz.addOperationLog(operationUser.getBaseUserId(), "超管账号["+operationUser.getMobile()+"]冻结用户["+user.getMobile()+"]");
                }else {
                    this.operationLogBiz.addOperationLog(operationUser.getBaseUserId(), "超管账号["+operationUser.getMobile()+"]解冻用户["+user.getMobile()+"]");
                }
            }
        }
        return result;
    }

    /**
     * 后台重置用户登录密码
     * @param resetPasswordModel
     * @param userId 操作人
     * @return
     */
    public int resetPassword(ResetPasswordModel resetPasswordModel, Long userId){
        CmsUser user = this.baseMapper.selectById(resetPasswordModel.getUserId());
        if (null == user){
            throw new ServiceException(this.i18nBiz.getMessage("msg.userNotExist"));
        }
        //密码加密
        String password = MD5Util.getEncryptedPwd(resetPasswordModel.getPassword(), LoginEnum.ENCRYPTION_KEY.Value());
        user.setPassword(password);
        user.setUpdateUser(userId);
        user.setUpdateTime(new Date());

        int result = this.baseMapper.updateById(user);
        if (result > 0){
            CmsUser operationUser = this.baseMapper.selectById(userId);
            //后台用户类型（0:普通用户,1:后台管理员）
            if (operationUser.getPcUserType().intValue() == 1){
                this.operationLogBiz.addOperationLog(operationUser.getBaseUserId(), "超管账号["+operationUser.getMobile()+"]重置用户["+user.getMobile()+"]登录密码为:"+resetPasswordModel.getPassword());
            }
        }

        return result;
    }

    /**
     * 更新用户信息-
     * @return
     */
    public int updateProject(String path){
        boolean flag = RemoveFolder.DeleteFolder(path);
        return flag ? 1 : 0;
    }

    /**
     * 修改用户手机号
     * @param updateUserMobileModel
     * @param userId 操作者ID
     * @return
     */
    public int updateUserMobile(UpdateUserMobileModel updateUserMobileModel, Long userId){
        CmsUser mobileUser = this.getUserByMobile(updateUserMobileModel.getMobile());
        if (null != mobileUser){
            throw new ServiceException(this.i18nBiz.getMessage("msg.mobileNumberRegistered"));
        }

        CmsUser user = this.baseMapper.selectById(updateUserMobileModel.getUserId());

        //旧手机号
        String oldMobile = user.getMobile();

        user.setMobile(updateUserMobileModel.getMobile());
        user.setUpdateTime(new Date());
        user.setUpdateUser(userId);

        int updateState = this.baseMapper.updateById(user);
        if (updateState > 0){
            CmsUser operationUser = this.baseMapper.selectById(userId);
            //后台用户类型（0:普通用户,1:后台管理员）
            if (operationUser.getPcUserType().intValue() == 1){
                this.operationLogBiz.addOperationLog(operationUser.getBaseUserId(), "超管账号["+operationUser.getMobile()+"]将手机号码为["+oldMobile+"]的用户,手机号改为:"+updateUserMobileModel.getMobile());
            }
        }

        return updateState;
    }

    /**
     * 更新用户为回收员
     * @param userId
     * @return
     */
    public int updateUserToRecoveryMmber(Long userId){
        int result = 0;
        CmsUser user = this.baseMapper.selectById(userId);
        user.setUserType(1);//用户类型（0:普通用户,1:回收员）

        result = this.baseMapper.updateById(user);
        return result;
    }

    /**
     * 更新回收员为普通用户
     * @param userId
     * @return
     */
    public int updateUserStopRecoveryMmber(Long userId){
        int result = 0;
        CmsUser user = this.baseMapper.selectById(userId);
        user.setUserType(0);//用户类型（0:普通用户,1:回收员）

        result = this.baseMapper.updateById(user);
        return result;
    }

}
